package com.xhwl.centiotdata.suppliersystem.eesd.wmzz;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xhwl.centiotdata.dao.ICampusUserStatisticsDao;
import com.xhwl.centiotdata.pojo.dto.eesd.EesdConfigDTO;
import com.xhwl.centiotdata.pojo.enums.eesd.EesdMethodEnum;
import com.xhwl.centiotdata.pollingtrigger.eesd.EesdDispatcher;
import com.xhwl.centiotdata.service.cent.IEesdCentService;
import com.xhwl.centiotdata.utils.ThreadPoolUtils;
import com.xhwl.common.dto.cent.energy.EesdElectricDTO;
import com.xhwl.common.dto.cent.energy.EesdElectricDetailDTO;
import com.xhwl.common.enums.device.DeviceTypeEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.utils.ChkUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

/**
 * @Author： lianghz
 * @Description：
 * @Date 2021/09/03/ 09:44
 */
@RestController
@Slf4j
public class EesdWmzzApiHandler {

    @Autowired
    private EesdDispatcher eesdDispatcher;
    /**
     * threadLocal
     */
    private static ThreadLocal<List<Map>> threadLocal = new ThreadLocal<>();

    private Date getCurrentDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH");
        Date date = new Date();
        String format = sdf.format(date);
        Date currentDate = new Date();
        try {
            currentDate = sdf.parse(format);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return currentDate;
    }

    @Autowired
    IEesdCentService iEesdCentService;

    private ExecutorService executor = ThreadPoolUtils.executor;

    @Autowired
    ICampusUserStatisticsDao iCampusUserStatisticsDao;

    /**
     * 拉取各种设备水电表环境的数据
     */
    public Object pullRecord(EesdConfigDTO configDTO) {
        switch (configDTO.getIsType()) {
            case 1:
                return pullElectric(configDTO);
            case 2:
                pullWater(configDTO);
                break;
            case 3:
                pullEnv(configDTO);
                break;
            default:
                throw new RuntimeException("望美项目未知类型");
        }
        return null;
    }

    /**
     * 获取电表
     */
    private Map<String, Object> pullElectric(EesdConfigDTO configDTO) {
        //获取电量详情
        String result = HttpUtil.get(configDTO.getElectricHost());
        List<Map> maps = JSON.parseArray(result, Map.class);
        if (maps == null) {
            log.info("获取望美项目当前数据总数量:0,被终止");
            return null;
        }
        log.info("获取望美项目当前数据总数量:{}", maps.size());
        List<EesdElectricDTO> devices = Lists.newLinkedList();
        List<EesdElectricDetailDTO> records = Lists.newLinkedList();
        EesdElectricDetailDTO eesdElectricDetailDTO;
        EesdElectricDTO eesdElectricDTO;
        Date currentDate = getCurrentDate();
        for (Map<String, String> entry : maps) {
            String deviceNo = entry.get("deviceNo");
            if (ChkUtil.isNotNull(deviceNo) && deviceNo.contains("BDZ")) {
                String deviceName = entry.get("deviceName");
                //倍率
                double rate = ChkUtil.isNull(entry.get("otherInfo")) ? 1d : Double.parseDouble(entry.get("otherInfo"));
                //设备
                eesdElectricDTO = new EesdElectricDTO();
                eesdElectricDTO.setId(deviceNo);
                eesdElectricDTO.setCode(deviceNo);
                eesdElectricDTO.setProductId(EesdMethodEnum.WMZZ.getId());
                eesdElectricDTO.setName(ChkUtil.isNull(entry.get("deviceName")) ? deviceNo : entry.get("deviceName"));
                eesdElectricDTO.setProjectId(configDTO.getProjectId());
                eesdElectricDTO.setFloorName(ChkUtil.isNull(entry.get("floor")) ? "" : entry.get("floor"));
                eesdElectricDTO.setDeviceType(DeviceTypeEnum.WATT_HOUR_METER.getCode());
                eesdElectricDTO.setOtherTypeName(ChkUtil.isNull(entry.get("deviceType")) ? "" : entry.get("deviceType"));
                eesdElectricDTO.setRate(rate);
                devices.add(eesdElectricDTO);
                //读数
                String value = ChkUtil.isNull(entry.get("value")) ? "0" : entry.get("value");

                BigDecimal val = new BigDecimal(value);
                eesdElectricDetailDTO = new EesdElectricDetailDTO();
                eesdElectricDetailDTO.setDeviceId(deviceNo);
                eesdElectricDetailDTO.setProjectId(configDTO.getProjectId());
                eesdElectricDetailDTO.setDeviceName(deviceName);
                eesdElectricDetailDTO.setName(deviceName);
                eesdElectricDetailDTO.setTime(currentDate);
                eesdElectricDetailDTO.setRate(rate);
                EesdElectricDetailDTO.ValueEntity detail = new EesdElectricDetailDTO.ValueEntity();
                detail.setValue(val.doubleValue());
                detail.setUnit("kW·h");
                eesdElectricDetailDTO.setValue(detail);
                eesdElectricDetailDTO.setDeviceType(DeviceTypeEnum.WATT_HOUR_METER.getCode());
                records.add(eesdElectricDetailDTO);
            }
        }

        List<CompletableFuture> futureList = Lists.newArrayList();
        CompletableFuture cf = CompletableFuture.runAsync(() -> iEesdCentService.baDeviceSync(devices), executor);
        futureList.add(cf);
        cf = CompletableFuture.runAsync(() -> iEesdCentService.baDeviceDetailSync(records), executor);
        futureList.add(cf);
        CompletableFuture.allOf((futureList.toArray(new CompletableFuture[]{}))).join();
        Map<String, Object> mt = Maps.newHashMap();
        mt.put("devices", devices);
        mt.put("records", records);
        return mt;
    }

    /**
     * 获取水表
     */
    private void pullWater(EesdConfigDTO configDTO) {

    }

    /**
     * 获取环境数据
     */
    private void pullEnv(EesdConfigDTO configDTO) {
        String result = HttpUtil.get(configDTO.getEnvironmentHost());
        List<Map> maps = JSON.parseArray(result, Map.class);
        if (CollectionUtil.isEmpty(maps)) {
            threadLocal.set(Lists.newArrayList());
            return;
        }
        threadLocal.set(maps);
    }

    /**
     * 对外接口
     */
    @RequestMapping(value = "/wmzz/pull")
    public ResultJson pullInfo(@RequestParam(value = "projectId") Integer projectId) {
        eesdDispatcher.executeWmzzEnvNumber();
        List<Map> vo = threadLocal.get();
        threadLocal.remove();
        List<Map<String, Object>> plist = Lists.newArrayList();
        for (Map<String, Object> entry : vo) {
            String originalName = (String) entry.get("deviceName");
            if (ChkUtil.isNull(originalName)) {
                continue;
            }
            originalName = originalName.trim();
            if (ChkUtil.isNull(originalName)) {
                continue;
            }
            if (originalName.length() < 3) {
                continue;
            }
            String name = originalName.substring(2);
            String lineGroupName = originalName.substring(0, 2);
            Map<String, Object> smap = Maps.newLinkedHashMap();
            smap.put("originalName", originalName);
            smap.put("lineGroup", entry.get("floor"));
            smap.put("lineGroupName", lineGroupName);
            smap.put("name", name);
            switch (name) {
                case "二氧化硫":
                    smap.put("key", "sulfurDioxide");
                    break;
                case "氢气压力":
                    smap.put("key", "hydrogenPressure");
                    break;
                case "氮气压力":
                    smap.put("key", "nitrogenPressure");
                    break;
                case "氮气流量":
                    smap.put("key", "nitrogenFlow");
                    break;
                case "氮氧化物":
                    smap.put("key", "nitrogenOxide");
                    break;
                case "烟气流量":
                    smap.put("key", "smokeFlow");
                    break;
                case "颗粒物":
                    smap.put("key", "particulateMatter");
                    break;
                default:
                    smap.put("key", smap.get("name"));
                    break;
            }
            String val = ChkUtil.isNull(entry.get("value")) ? "0" : entry.get("value") + "";
            smap.put("value", new BigDecimal(val));
            plist.add(smap);
        }
        return ResultJson.success(plist);
    }
}
